home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’92 / NotificationMon ƒ / NotificationMon.ƒ / Source / NotificationMon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-22  |  5.7 KB  |  305 lines  |  [TEXT/KAHL]

  1. #include "NotificationMon.h"
  2. #include <GestaltTalk.h>
  3. #include "Event.h"
  4.  
  5. short GetSleepTime()
  6. {
  7.     if(InBackGround)
  8.         return MainView->prefs.backTime;
  9.     else
  10.         return MainView->prefs.foreTime;
  11. }
  12.  
  13. Boolean IsNotificationDoc(WindowPeek wp)
  14. {
  15.     return (wp->windowKind == notifyKind);
  16. }
  17.  
  18. void InitNotificationDoc(notificationDoc *nmd)
  19. {
  20.     Handle        emptyMessage;
  21.     GrafPtr        savePort;
  22.     FontInfo    fi;
  23.     
  24.     nmd->ncount = 0;
  25.     nmd->nHead = nil;
  26.     nmd->nTail = nil;
  27.     nmd->vScroll = nil;
  28.     nmd->nSelection = 0;
  29.  
  30.     GetPort(&savePort);
  31.     SetPort(&nmd->nWin);
  32.     GetFontInfo(&fi);
  33.     nmd->lineHt = fi.ascent + fi.descent + fi.leading;
  34.     emptyMessage = GetResource('STR ',128);
  35.     HLock(emptyMessage);
  36.     nmd->longestLine = StringWidth(*emptyMessage) + RIGHT_MARGIN;
  37.     HUnlock(emptyMessage);
  38.     SetPort(savePort);
  39. }
  40.  
  41. void     RegisterNotificationMonitor()
  42. {
  43.     GestaltTalkPB        gPB;
  44.     OSErr                err;
  45.     ProcessSerialNumber    psn;
  46.     
  47.     if(!MainView) return;
  48.      
  49.     err = GetCurrentProcess(&psn);
  50.     if(err) {
  51.         DebugStr("\pError in GetCurrentProcess");
  52.     }
  53.     
  54.     gPB.command = gregister;
  55.     gPB.datalength = sizeof(ProcessSerialNumber);
  56.     gPB.data = &psn;
  57.     gPB.gtData = nil;
  58.     
  59.     err = GestaltTalk(&gPB);
  60.     if(err) {
  61.         DebugStr("\p GestaltTalk register failed.");
  62.     }
  63. }
  64.  
  65. void     UnregisterNotificationMonitor()
  66. {
  67.     GestaltTalkPB        gPB;
  68.     OSErr                err;
  69.     
  70.     if(!MainView) return;
  71.      
  72.     gPB.command = gunregister;
  73.     gPB.datalength = 0;
  74.     gPB.data = nil;
  75.     gPB.gtData = nil;
  76.     
  77.     err = GestaltTalk(&gPB);
  78.     if(err) {
  79.         DebugStr("\p GestaltTalk UNregister failed.");
  80.     }
  81. }
  82.  
  83. notificationDoc *NewNotificationDoc(short wID)
  84. {
  85.     notificationDoc *nmd;
  86.     
  87.     nmd = NewPtr(sizeof(notificationDoc));
  88.     if(!nmd) {
  89.         DebugStr("\pMemory Allocation Fail. in NewNotficationDoc");
  90.     }
  91.     
  92.     (void) GetNewWindow(wID,&nmd->nWin,(WindowPtr)-1);
  93.     nmd->nWin.windowKind = notifyKind;
  94.  
  95.     InitNotificationDoc(nmd);
  96.     InitNotificationPrefs(nmd);
  97.     InitNotificationWindow(nmd);
  98.     
  99.     ShowWindow(&nmd->nWin);
  100.     return nmd;
  101. }
  102.  
  103. void AddNotification(Str255 notification, notificationDoc *nmd)
  104. {
  105.     Handle         icon = nil, sound = nil, message = nil;
  106.     short         err = 0;
  107.     Size        msgLen = 0;
  108.     nnH            nCurs;
  109.     GrafPtr        savePort;
  110.     short        msgPixLen;
  111.     Rect        content;
  112.     
  113.     msgLen = notification[0] +1;
  114.     message = NewHandle(msgLen);
  115.     if(!message) {
  116.         DebugStr("\pNewHandle fail in AddNotification[1]");
  117.         return;
  118.     }
  119.     BlockMove(notification, *message, msgLen);
  120.     
  121.     nCurs = NewHandle(sizeof(neoNotification));
  122.     if(!nCurs) {
  123.         DebugStr("\pNewHandle fail in AddNotification[2]");
  124.         return;
  125.     }
  126.     (**nCurs).icon = icon;
  127.     (**nCurs).sound = sound;
  128.     (**nCurs).message = message;
  129.     (**nCurs).next = nil;
  130.  
  131.     if(nmd->nHead == nil) {
  132.         nmd->nHead = nmd->nTail = nCurs;
  133.     }
  134.     else {
  135.         (**(nmd->nTail)).next = nCurs;
  136.         nmd->nTail = nCurs;
  137.     }
  138.     nmd->ncount++;
  139.      
  140.      GetPort(&savePort);
  141.      SetPort(&nmd->nWin);
  142.      msgPixLen = StringWidth(notification) + RIGHT_MARGIN;
  143.      if(msgPixLen > nmd->longestLine)
  144.          nmd->longestLine = msgPixLen;
  145.  
  146.     UpdateScrollMax(nmd);
  147.     NotificationCheckScrollVis();
  148.  
  149.     content = nmd->nWin.port.portRect;
  150.     content.right -= 16;
  151.     InvalRect(&content);
  152.  
  153.      SetPort(savePort);
  154. }
  155.  
  156. void KillNotifications(notificationDoc *nmd)
  157. {
  158.     nnH            nCurs;
  159.     GrafPtr        savePort;
  160.     
  161.     if(!nmd->ncount) return;
  162.     
  163.     while(nmd->ncount--) {
  164.         nCurs = nmd->nHead;
  165.         if((**nCurs).icon)
  166.             DisposHandle((**nCurs).icon);
  167.         if((**nCurs).sound)
  168.             DisposHandle((**nCurs).sound);
  169.         if((**nCurs).message)
  170.             DisposHandle((**nCurs).message);
  171.         nmd->nHead = (**nCurs).next;
  172.         DisposHandle(nCurs);
  173.     }
  174.  
  175.     nmd->ncount = 0;
  176.     nmd->nHead = nil;
  177.     nmd->nTail = nil;
  178.     
  179.     GetPort(&savePort);
  180.     SetPort(&nmd->nWin);
  181.     InvalRect(&nmd->nWin.port.portRect);
  182.     SetPort(savePort);
  183.     
  184. }
  185.  
  186. nnH    GetNotificationEntryByNumber(notificationDoc *nmd, short num)
  187. {
  188.     short    count;
  189.     nnH        target;
  190.  
  191.     if(num > nmd->ncount)    return nmd->nTail;
  192.     if(num < 1)             return nmd->nHead;
  193.     
  194.     target = nmd->nHead;
  195.     while(--num) {
  196.         target = (**target).next;
  197.     }
  198.     
  199.     return target;
  200. }
  201.  
  202. void DrawNotification(nnH n)
  203. {
  204.     if(!n) {
  205.         DebugStr("\p n was nil in DrawNotification");
  206.         return;
  207.     }
  208.     HLock((Handle)(**n).message);
  209.     DrawString(*(**n).message);
  210.     HUnlock((Handle)(**n).message);
  211. }
  212.  
  213. void UpdateNotifications(notificationDoc *nmd, short first)
  214. {
  215.     nnH            nCurs;
  216.     short        numToDraw;
  217.     FontInfo    fi;
  218.     short        i;
  219.     GrafPtr        savePort;
  220.     Handle        emptyMessage;
  221.     Rect        clip, selRect;
  222.     
  223.     GetPort(&savePort);    
  224.     SetPort(&nmd->nWin.port);
  225.  
  226.     clip = nmd->nWin.port.portRect;
  227.     clip.right -= 16;    
  228.     ClipRect(&clip);
  229.  
  230.     EraseRect(&clip);
  231.  
  232.     if(!nmd->ncount) {
  233.         MoveTo(4,nmd->lineHt);
  234.         emptyMessage = GetResource('STR ',128);
  235.         HLock(emptyMessage);
  236.         DrawString(*emptyMessage);
  237.         HUnlock(emptyMessage);
  238.         return;
  239.     }
  240.  
  241.     nCurs = GetNotificationEntryByNumber(nmd,first);
  242.     
  243.     for(i = 0; i <= nmd->ncount - first; i++) {
  244.         if(nmd->nSelection && (i == nmd->nSelection) ) {
  245.             selRect = nmd->nWin.port.portRect;
  246.             selRect.right -= 16;
  247.             selRect.bottom = selRect.top + nmd->lineHt;
  248.             if(nmd->nSelection > 1)
  249.                 OffsetRect(&selRect, 0, nmd->lineHt * nmd->nSelection);
  250.             FillRect(&selRect,black);
  251.             MoveTo(4,(i+1)*nmd->lineHt);
  252.             TextMode(srcXor);
  253.             DrawNotification(nCurs);
  254.             TextMode(srcOr);
  255.         } else {
  256.             MoveTo(4,(i+1)*nmd->lineHt);
  257.             DrawNotification(nCurs);
  258.         }
  259.         nCurs = (**nCurs).next;
  260.         if(!nCurs) break;
  261.     }
  262.     
  263.     
  264.     ClipRect(&nmd->nWin.port.portRect);
  265.     SetPort(savePort);
  266. }
  267.  
  268.  
  269. void CheckNotifications()
  270. {
  271.     GestaltTalkPB    gPB;
  272.     OSErr            err;
  273.     Str255            message;
  274.     
  275.     if(!MainView) return;
  276.      
  277.     gPB.command = gstatus;
  278.     gPB.datalength = 0;
  279.     gPB.data = nil;
  280.     gPB.gtData = nil;
  281.     
  282.     err = GestaltTalk(&gPB);
  283.     
  284.     if(err) {
  285.         error("\p CheckNotification failed.",err);
  286.         return;
  287.     }
  288.  
  289.     if(!gPB.datalength) return;
  290.  
  291.     gPB.command = gread;
  292.     /* using datalength returned from status call */
  293.     gPB.data = message;
  294.     gPB.gtData = nil;
  295.     
  296.     err = GestaltTalk(&gPB);
  297.  
  298.     if(err) {
  299.         error("\p CheckNotifications read error. ",err);
  300.     }
  301.  
  302.     AddNotification(message, MainView);
  303.     PostNotificationIcon();
  304.  
  305. }